﻿/*
通用表单验证方法
Validform version 5.0
By sean during April 7, 2010 - June 27, 2012
For more information, please visit http://validform.rjboy.cn
Validform is available under the terms of the MIT license.
*/

(function ($, win, undef) {
    var errorobj = null, //指示当前验证失败的表单元素;
		msgobj = null, //pop box object 
		msghidden = true; //msgbox hidden?
    var tipmsg = {};
    var tipmsgCN = {//默认提示文字(中文);
        tit: "提示信息",
        w: "",//"请输入正确信息！",
        r: "",//"通过信息验证！",
        c: "正在检测信息…",
        s: "",//"请填入信息！",
        v: "所填信息没有经过验证，请稍后…",
        p: "正在提交数据…",
        err: "出错了！请检查提交地址或返回数据格式是否正确！",
        abort: "Ajax操作被取消！"
    }
    var tipmsgEN = {//默认提示文字(英文);
        tit: "information",
        w: "Please enter a valid information！",
        r: "Through information validation！",
        c: "Is testing information is correct...",
        s: "Please fill in the information！",
        v: "Filled information has not been verified, please wait...",
        p: "Are submitting data...",
        err: "Wrong!Please check submitted to the address or return the correct data format!",
        abort: "Ajax operation has been canceled！"
    }
    $.Tipmsg = tipmsg;

    var Validform = function (forms, settings, inited) {
        var settings = $.extend({}, Validform.defaults, settings);
        settings.datatype && $.extend(Validform.util.dataType, settings.datatype);

        var brothers = this;
        brothers.tipmsg = {};
        brothers.settings = settings;
        brothers.forms = forms;
        brothers.objects = [];

        if (settings && settings.defaultMsgType && settings.defaultMsgType == "en") {
            tipmsg = tipmsgEN;
        } else {
            tipmsg = tipmsgCN;
        }

        if (settings && settings.tiptype && settings.tiptype == 3) {
            brothers.settings.tiptype = function (msg, o, cssctl) {
                if (!o.obj.is("form")) {
                    o.obj.parent().siblings().find(".Validform_checktip").hide();
                    var objtip = o.obj.parent().nextAll().find(".Validform_checktip").first().show(); //"div div.Validform_checktip");//.find(".Validform_checktip");
                    cssctl(objtip, o.type);
                    objtip.text(msg);
                    //Validform_checktip层中如果指定showRight="false"属性值则验证通过后不显示提示信息
                    if (objtip.attr("showRight") && o.type == 2 && objtip.attr("showRight") == "false") {
                        objtip.hide();
                    }
                }
            };
        }

        if (settings && settings.tiptype && settings.tiptype == 4) {
            brothers.settings.tiptype = function (msg, o, cssctl) {
                if (!o.obj.is("form")) {
                    o.obj.siblings(".Validform_checktip").hide();
                    o.obj.siblings(".infotip").hide();
                    var objtip = o.obj.nextAll(".Validform_checktip").first().show();
                    cssctl(objtip, o.type);
                    objtip.text(msg);
                    //Validform_checktip层中如果指定showRight="false"属性值则验证通过后不显示提示信息
                    if (objtip.attr("showRight") && o.type == 2 && objtip.attr("showRight") == "false") {
                        objtip.hide();
                    }
                }
            };
        }

        //创建子对象时不再绑定事件;
        if (inited === true) {
            return false;
        }

        forms.each(function (n) {
            var $this = $(this);

            //防止表单按钮双击提交两次;
            //this.status = "normal"; //normal | posting | posted;

            //让每个Validform对象都能自定义tipmsg;	
            $this.data("tipmsg", brothers.tipmsg);

            //bind the blur event;
            $this.find("[datatype]").bind("blur", function () {

                var flag = true,
					_this;
                errorobj = _this = $(this);
                var inputval = Validform.util.getValue.call($this, $(this));

                flag = Validform.util.regcheck.call($this, $(this).attr("datatype"), inputval, $(this));
                if (!flag.passed) {
                    //取消正在进行的ajax验证;
                    Validform.util.abort.call(_this[0]);
                    _this.addClass("Validform_error");
                    Validform.util.showmsg.call($this, flag.info, settings.tiptype, { obj: $(this), type: flag.type, sweep: settings.tipSweep }, "hide"); //当tiptype=1的情况下，传入"hide"则让提示框不弹出,tiptype=2的情况下附加参数"hide"不起作用;
                } else {
                    if ($(this).attr("ajaxurl")) {
                        var inputobj = $(this);
                        var subpost = arguments[1];
                        if ($.trim(inputobj.attr("tip")) && inputval === $.trim(inputobj.attr("tip"))) {
                            inputval = "";
                        }
                        if (inputobj[0].valid === "posting") { return false; }
                        if ($(this).attr("servercheck") && $(this).attr("servercheck") == "false") {
                            inputobj[0].valid = "true";
                            _this.removeClass("Validform_error");
                            if (subpost === "postform") {
                                $this.trigger("submit");
                            }
                            return true;
                        }
                        if ($(this).attr("ignore") && $(this).attr("ignore") == "ignore" && inputval == "") {
                            inputobj[0].valid = "true";
                            $(this).attr("cked", "cked");
                            _this.removeClass("Validform_error");
                            if (subpost === "postform") {
                                $this.trigger("submit");
                            }
                            var strMsg = brothers.tipmsg.r || tipmsg.r;
                            Validform.util.showmsg.call($this, strMsg, settings.tiptype, { obj: inputobj, type: 4, sweep: settings.tipSweep }, "hide");
                            return true;
                        }
                        var paramData = '';
                        var paramName = '';
                        if ($(this).attr("getvaluefrom")) {
                            var ids = $(this).attr("getvaluefrom").split(',');
                            var isContainSelf = false; //定义ID中是否包含当前控件ID
                            var currentId = $(this).attr("id");
                            $.each(ids, function (i, id) {
                                if (id == currentId) {
                                    isContainSelf = true;
                                }
                                var curObj = $('#' + id);
                                var strName = curObj.attr("name") ? curObj.attr("name") : id;
                                var strValue = Validform.util.getValue.call($this, curObj);
                                if ($.trim(curObj.attr("tip")) && strValue === $.trim(curObj.attr("tip"))) {
                                    strValue = "";
                                }
                                paramData = paramData + '&' + strName + '=' + strValue;
                                paramName = paramName + strName + ',';
                            });
                            if (!isContainSelf) {
                                paramData = paramData + '&' + $(this).attr("name") + "=" + inputval;
                                paramName = paramName + $(this).attr("name") + ',';
                            }
                            paramData = paramData.substr(1, paramData.length);
                            paramName = paramName.substr(0, paramName.length - 1);
                        } else {
                            paramData = $(this).attr("name") + "=" + inputval;
                            paramName = $(this).attr("name");
                        }
                        paramData = paramData + '&name=' + paramName;

                        inputobj[0].valid = "posting";
                        Validform.util.showmsg.call($this, brothers.tipmsg.c || tipmsg.c, settings.tiptype, { obj: inputobj, type: 1, sweep: settings.tipSweep }, "hide");

                        Validform.util.abort.call(_this[0]);
                        _this[0].ajax = $.ajax({
                            type: "POST",
                            url: inputobj.attr("ajaxurl"),
                            data: paramData,
                            dataType: "text",
                            cache: false,
                            success: function (s) {
                                //返回值JSON格式：({ result:'y/n',msg:''}）
                                if (s != null && s != "") {
                                    var json = eval(s);
                                    if (json.result == "y") {
                                        inputobj[0].valid = "true";
                                        _this.removeClass("Validform_error");
                                        errorobj = null;
                                        var strMsg = (json.msg && json.msg != "") ? json.msg : (brothers.tipmsg.r || tipmsg.r);
                                        Validform.util.showmsg.call($this, strMsg, settings.tiptype, { obj: inputobj, type: 2, sweep: settings.tipSweep }, "hide");
                                        if (subpost === "postform") {
                                            $this.trigger("submit");
                                        }
                                    } else {
                                        inputobj[0].valid = json.result;
                                        _this.addClass("Validform_error");
                                        var strMsg = (json.msg && json.msg != "") ? json.msg : (brothers.tipmsg.r || tipmsg.r);
                                        Validform.util.showmsg.call($this, strMsg, settings.tiptype, { obj: inputobj, type: 3, sweep: settings.tipSweep });
                                    }

                                }
                                _this[0].ajax = null;
                            },
                            error: function () {
                                inputobj[0].valid = brothers.tipmsg.err || tipmsg.err;
                                _this.addClass("Validform_error");
                                _this[0].ajax = null;
                                Validform.util.showmsg.call($this, brothers.tipmsg.err || tipmsg.err, settings.tiptype, { obj: inputobj, type: 3, sweep: settings.tipSweep });
                            }
                        });
                    } else {
                        _this.removeClass("Validform_error");
                        errorobj = null;
                        Validform.util.showmsg.call($this, flag.info, settings.tiptype, { obj: $(this), type: flag.type, sweep: settings.tipSweep }, "hide");
                    }
                }
            });

            settings.showInfo && $this.find("[datatype]").focusin(function () {
                if (this.timeout) { clearTimeout(this.timeout); }
                var infoObj = $(this).parent().next().find(".info");
                infoObj.show();
                var checkTipObj = infoObj.parent().nextAll().find(".Validform_checktip").first();
                if ($(this).parent().nextAll().find(".passwordStrength").length != 0) {
                    $(this).parent().nextAll().find(".passwordStrength").hide();
                }
                //if (infoObj.parent().nextAll().find(".Validform_right").first().length != 0) {
                //    if (checkTipObj.attr("showRight") && checkTipObj.attr("showRight") == "false")
                //        checkTipObj.hide();
                //else
                //    checkTipObj.show();
                //    return;
                //}
                infoObj.parent().nextAll().find(".Validform_checktip").first().hide();

            }).focusout(function () {
                var infoObj = $(this).parent().next().find(".info");
                infoObj.hide().parent().siblings().find(".Validform_checktip").hide();
                var checkTipObj = infoObj.parent().nextAll().find(".Validform_checktip").first();
                if (infoObj.parent().nextAll().find(".Validform_right").first().length != 0) {
                    if (checkTipObj.attr("showRight") && checkTipObj.attr("showRight") == "false") {
                        checkTipObj.hide();
                    }
                    else {
                        checkTipObj.show();
                    }
                    return;
                }
                //this.timeout = setTimeout(function() {
                infoObj.parent().nextAll().find(".Validform_wrong,.Validform_loading").first().show();
                //}, 0);

            });

            //点击表单元素，默认文字消失效果;
            Validform.util.hasDefaultText.call($this);

            //表单元素值比较时的信息提示增强;
            Validform.util.recheckEnhance.call($this);

            //plugins here to start;
            if (settings.usePlugin) {
                Validform.util.usePlugin.call($this, settings.usePlugin, settings.tiptype, settings.tipSweep, n);
            }

            //enhance info feedback for checkbox & radio;
            $this.find(":checkbox[datatype],:radio[datatype]").each(function () {
                var _this = $(this);
                var name = _this.attr("name");
                $this.find("[name='" + name + "']").filter(":checkbox,:radio").bind("click", function () {
                    //避免多个事件绑定时的取值滞后问题;
                    setTimeout(function () {
                        _this.trigger("blur");
                    }, 0);
                });

            });

            settings.btnSubmit && $this.find(settings.btnSubmit).bind("click", function () {
                var subflag = Validform.util.submitForm.call($this, settings);
                subflag === undef && (subflag = true);
                if (subflag === true) {
                    $this[0].submit();
                }
                return false;
            });

            $this.submit(function () {
                var subflag = Validform.util.submitForm.call($this, settings);
                subflag === undef && (subflag = true);
                return subflag;
            });

            $this.find("[type='reset']").add($this.find(settings.btnReset)).bind("click", function () {
                Validform.util.resetForm.call($this);
                return false;
            });

        });

        //预创建pop box;
        if (settings.tiptype == 1 || (settings.tiptype == 2 && settings.ajaxPost)) {
            creatMsgbox();
        }
    }

    Validform.defaults = {
        tiptype: 1,
        tipSweep: false,
        showAllError: false,
        postonce: false,
        ajaxPost: false,
        showInfo: false
    }

    Validform.util = {
        dataType: {
            "math": /^[\d]+\.?\d*$/, ///^(.+?)(\d+)-(\d+)$/,
            "nmath": /^(-?\d+)(\.\d+)?$/, ///^(.+?)(\d+)-(\d+)$/,
            "*": /[\w\W]+/,
            "*6-16": /^[\w\W]{6,16}$/,
            "n": /^\d+$/,
            "n6-16": /^\d{6,16}$/,
            "s": /^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]+$/,
            "s6-18": /^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]{6,18}$/,
            "p": /^[0-9]{6}$/,
            "m": /^[0-9]{11}$/, // /^13[0-9]{9}$|15[0-9]{9}$|18[0-9]{9}$/,
            "e": /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
            "url": /^(\w+:\/\/)?\w+(\.\w+)+.*$/,
            "n1-2": /^[1-2]{1}$/, //1或2
            "*1-50": /^[^\s]{1,50}$/, //1到50个字符
            "*1-128": /^[^\s]{1,128}$/, //1到128个字符        
            "*1-256": /[\w\W]{1,256}$/,
            "*1-500": /[\w\W]{1,500}$/, //1到500个字符
            "*6-20": /^[0-9A-Za-z]{6,20}$/, //6到20个字符,只能输数字和英文字母
            "*1-20": /^[0-9A-Za-z]{1,20}$/, //1到20个字符,只能输数字和英文字母
            "*15-18": /^[0-9A-Za-z]{15,18}$/,
            "c6": /^[0-9A-Za-z]{6}$/, //6到20个字符,只能输数字和英文字母
            "c9": /^[0-9A-Za-z]{9}$/, //6到20个字符,只能输数字和英文字母
            "n7-128": /^\d{7,128}$/,
            "z2-4": /^[\u4E00-\u9FA5\uf900-\ufa2d]{2,4}$/, //2到4个中文
            "s4": /^[0-9A-Za-z]{4}$/,
            "z1-25": /^[\u4E00-\u9FA5\uf900-\ufa2d]{1,25}$/, //只能输中文
            "cn": /^[\u4E00-\u9FA5\uf900-\ufa2d\s]{1,}$/, //只能输中文
            "cnne": /^[\u4E00-\u9FA5\uf900-\ufa2d\s0-9A-Za-z,.;，。；\/\\-]{1,}$/, //只能输中文、数字、英文
            "en": /^[0-9A-Za-z\.\s_]{1,}$/, //只能输英文、数字、点和空格和下划线
            "enAndNumAndDownline": /^[0-9A-Za-z_]{1,}$/, //只能输英文、数字、点和空格和下划线
            "enChar": /^[A-Za-z]+$/, //只能输入英文26个字母（大小写）
            "enCharAndSpace": /^[A-Za-z\s]+$/, //只能输入英文26个字母和空格（大小写）
            "tel": /^[0-9-]{6,34}$/, ///^\d{7,8}(-\d{3,4})?$/,//固定电话（不包括区号），分机号码请用"-"分隔
            "area": /^0[0-9]{1,4}$/, //固定电话区号，以0开头，四位以内数字
            "fax": /^[0-9-]{1,14}$/, //传真（不包括区号）
            "faxAll": /^[0-9-]{1,50}$/,
            "express": /^[^<>＜＞]+$/,
            "notCN": function (gets, obj, curform, regxp) {//非中文
                if (gets == "") return false;
                var reg1 = /[\u4E00-\u9FA5\uf900-\ufa2d]/;
                if (gets.match(reg1) != null) { return false; }
                return true;
            },
            "pwd": /^[0-9A-Za-z_]{6,20}$/, //只能输英文、数字和下划线
            "pwd2": /^[^\s]{6,20}$/, //密码,6到20个字符
            "*notSP": /^[^<>＜＞]+$/, //*非法字符<>＜＞
            "date": /^(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.)(?:0?2\1(?:29))$)|(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))$/, //日期，例如:2000-01-01
            "phone": function (gets, obj, curform, regxp) {
                /*参数gets是获取到的表单元素值，
                obj为当前表单元素，
                curform为当前验证的表单，
                regxp为内置的一些正则表达式的引用。*/

                var reg1 = regxp["m"],
					reg2 = /[\d]{7}/,
					mobile = curform.find(".mobile");

                if (reg1.test(mobile.val())) { return true; }
                if (reg2.test(gets)) { return true; }

                return false;
            }
        },

        toString: Object.prototype.toString,

        getValue: function (obj) {
            var inputval,
				curform = this;

            if (obj.is(":radio")) {
                inputval = curform.find(":radio[name='" + obj.attr("name") + "']:checked").val();
                inputval = inputval === undef ? "" : inputval;
            } else if (obj.is(":checkbox")) {
                inputval = curform.find(":checkbox[name='" + obj.attr("name") + "']:checked").val();
                inputval = inputval === undef ? "" : inputval;
            } else {
                inputval = obj.val();
            }
            return $.trim(inputval);
        },

        recheckEnhance: function () {
            var curform = this;
            curform.find("input[recheck]").each(function () {
                var _this = $(this);
                var recheckinput = curform.find("input[name='" + $(this).attr("recheck") + "']");
                recheckinput.bind("keyup", function () {
                    if (recheckinput.val() == _this.val() && recheckinput.val() != "") {
                        if (recheckinput.attr("tip")) {
                            if (recheckinput.attr("tip") == recheckinput.val()) { return false; }
                        }
                        _this.trigger("blur");
                    }
                }).bind("blur", function () {
                    if (recheckinput.val() != _this.val() && _this.val() != "") {
                        if (_this.attr("tip")) {
                            if (_this.attr("tip") == _this.val()) { return false; }
                        }
                        _this.trigger("blur");
                    }
                });
            });
        },

        hasDefaultText: function () {
            this.find("[tip]").each(function () {//tip是表单元素的默认提示信息,这是点击清空效果;
                var defaultvalue = $(this).attr("tip");
                var altercss = $(this).attr("altercss");
                $(this).focus(function () {
                    if ($(this).val() == defaultvalue) {
                        $(this).val('');
                        if (altercss) { $(this).removeClass(altercss); }
                    }
                }).blur(function () {
                    if ($.trim($(this).val()) === '') {
                        $(this).val(defaultvalue);
                        if (altercss) { $(this).addClass(altercss); }
                    }
                });
            });
        },

        usePlugin: function (plugin, tiptype, tipSweep, n) {
            /*
            plugin:settings.usePlugin;
            tiptype:settings.tiptype;
            tipSweep:settings.tipSweep;
            n:当前表单的索引;
            */

            var curform = this;
            //swfupload;
            if (plugin.swfupload) {
                var swfuploadinput = curform.find("input[plugin='swfupload']").val(""),
					custom = {
					    custom_settings: {
					        form: curform,
					        showmsg: function (msg, type) {
					            Validform.util.showmsg.call(curform, msg, tiptype, { obj: swfuploadinput, type: type, sweep: tipSweep });
					        }
					    }
					};

                custom = $.extend(true, {}, plugin.swfupload, custom);
                if (typeof (swfuploadhandler) != "undefined") { swfuploadhandler.init(custom, n); }

            }

            //datepicker;
            if (plugin.datepicker) {
                if (plugin.datepicker.format) {
                    Date.format = plugin.datepicker.format;
                    delete plugin.datepicker.format;
                }
                if (plugin.datepicker.firstDayOfWeek) {
                    Date.firstDayOfWeek = plugin.datepicker.firstDayOfWeek;
                    delete plugin.datepicker.firstDayOfWeek;
                }

                var datepickerinput = curform.find("input[plugin='datepicker']");
                plugin.datepicker.callback && datepickerinput.bind("dateSelected", function () {
                    var d = new Date($.event._dpCache[this._dpId].getSelected()[0]).asString(Date.format);
                    plugin.datepicker.callback(d, this);
                });

                datepickerinput.datePicker(plugin.datepicker);
            }

            //passwordstrength;
            if (plugin.passwordstrength) {
                plugin.passwordstrength.showmsg = function (obj, msg, type) {
                    Validform.util.showmsg.call(curform, msg, tiptype, { obj: obj, type: type, sweep: tipSweep }, "hide");
                };
                curform.find("input[plugin*='passwordStrength']").passwordStrength(plugin.passwordstrength);
            }

            //jqtransform;
            if (plugin.jqtransform) {
                var jqTransformHideSelect = function (oTarget) {
                    var ulVisible = $('.jqTransformSelectWrapper ul:visible');
                    ulVisible.each(function () {
                        var oSelect = $(this).parents(".jqTransformSelectWrapper:first").find("select").get(0);
                        //do not hide if click on the label object associated to the select
                        if (!(oTarget && oSelect.oLabel && oSelect.oLabel.get(0) == oTarget.get(0))) { $(this).hide(); }
                    });
                };

                /* Check for an external click */
                var jqTransformCheckExternalClick = function (event) {
                    if ($(event.target).parents('.jqTransformSelectWrapper').length === 0) { jqTransformHideSelect($(event.target)); }
                };

                var jqTransformAddDocumentListener = function () {
                    $(document).mousedown(jqTransformCheckExternalClick);
                };

                if (plugin.jqtransform.selector) {
                    curform.find(plugin.jqtransform.selector).filter('input:submit, input:reset, input[type="button"]').jqTransInputButton();
                    curform.find(plugin.jqtransform.selector).filter('input:text, input:password').jqTransInputText();
                    curform.find(plugin.jqtransform.selector).filter('input:checkbox').jqTransCheckBox();
                    curform.find(plugin.jqtransform.selector).filter('input:radio').jqTransRadio();
                    curform.find(plugin.jqtransform.selector).filter('textarea').jqTransTextarea();
                    if (curform.find(plugin.jqtransform.selector).filter("select").length > 0) {
                        curform.find(plugin.jqtransform.selector).filter("select").jqTransSelect();
                        jqTransformAddDocumentListener();
                    }

                } else {
                    curform.jqTransform();
                }

                curform.find(".jqTransformSelectWrapper").find("li a").click(function () {
                    curform.find("select").trigger("blur");
                });
            }

        },

        regcheck: function (datatype, gets, obj) {
            /*
            datatype:datatype;
            gets:inputvalue;
            obj:input object;
            */
            var curform = this,
				info = null,
				passed = false,
				type = 3; //default set to wrong type, 2,3,4;

            //ignore;
            if (obj.attr("ignore") === "ignore" && (gets === "" || gets === $.trim(obj.attr("tip")))) {
                if (obj.attr("cked")) {
                    info = "";
                }

                return {
                    passed: true,
                    type: 4,
                    info: info == null ? '' : info
                };
            }

            if (obj.attr("ignore") === "ignore") {
                obj.attr("cked", "cked"); //do nothing if is the first time the ignore triggered;
            }

            //default value;
            if ($.trim(obj.attr("tip")) && gets === $.trim(obj.attr("tip"))) {
                return {
                    passed: false,
                    type: 3,
                    info: obj.attr("nullmsg") || curform.data("tipmsg").s || tipmsg.s
                };
            }

            if (Validform.util.toString.call(Validform.util.dataType[datatype]) == "[object Function]") {
                passed = Validform.util.dataType[datatype](gets, obj, curform, Validform.util.dataType);
                if (passed === true) {
                    type = 2;
                    info = curform.data("tipmsg").r || tipmsg.r;

                    if (obj.attr("recheck")) {
                        var theother = curform.find("input[name='" + obj.attr("recheck") + "']:first");
                        if (gets != theother.val()) {
                            passed = false;
                            type = 3;
                            info = obj.attr("errormsg") || curform.data("tipmsg").w || tipmsg.w;
                        }
                    }

                } else {
                    info = passed || obj.attr("errormsg") || curform.data("tipmsg").w || tipmsg.w;
                    passed = false;
                    if (gets === "") {//验证不通过且为空时;
                        return {
                            passed: false,
                            type: 3,
                            info: obj.attr("nullmsg") || curform.data("tipmsg").s || tipmsg.s
                        };
                    }
                }

                return {
                    passed: passed,
                    type: type,
                    info: info
                };

            }

            if (!(datatype in Validform.util.dataType)) {
                var mac = datatype.match(Validform.util.dataType["math"]),
					temp;

                if (!mac) {
                    return false;
                }

                for (var name in Validform.util.dataType) {
                    temp = name.match(Validform.util.dataType["math"]);
                    if (!temp) { continue; }
                    if (mac[1] === temp[1]) {
                        var str = Validform.util.dataType[name].toString(),
							param = str.match(/\/[mgi]*/g)[1].replace("\/", ""),
							regxp = new RegExp("\\{" + temp[2] + "," + temp[3] + "\\}", "g");
                        str = str.replace(/\/[mgi]*/g, "\/").replace(regxp, "{" + mac[2] + "," + mac[3] + "}").replace(/^\//, "").replace(/\/$/, "");
                        Validform.util.dataType[datatype] = new RegExp(str, param);
                        break;
                    }
                }
            }

            if (Validform.util.toString.call(Validform.util.dataType[datatype]) == "[object RegExp]") {
                passed = Validform.util.dataType[datatype].test(gets);
                if (passed) {
                    type = 2;
                    info = curform.data("tipmsg").r || tipmsg.r;

                    if (obj.attr("recheck")) {
                        var theother = curform.find("input[name='" + obj.attr("recheck") + "']:first");
                        if (gets != theother.val()) {
                            passed = false;
                            type = 3;
                            info = obj.attr("errormsg") || curform.data("tipmsg").w || tipmsg.w;
                        }
                    }

                } else {
                    info = obj.attr("errormsg") || curform.data("tipmsg").w || tipmsg.w;

                    if (gets === "") {
                        return {
                            passed: false,
                            type: 3,
                            info: obj.attr("nullmsg") || curform.data("tipmsg").s || tipmsg.s
                        };
                    }
                }

                return {
                    passed: passed,
                    type: type,
                    info: info
                };
            }

            return {
                passed: false,
                type: 3,
                info: curform.data("tipmsg").w || tipmsg.w
            };

        },

        showmsg: function (msg, type, o, show) {//o:{obj:当前对象, type:1=>正在检测 | 2=>通过}, show用来判断tiptype=1的情况下是否弹出信息框;
            $.extend(o, { curform: this });

            if (typeof type == "function") {
                if (!(o.sweep && show == "hide")) {
                    type(msg, o, Validform.util.cssctl);
                }
                return false;
            }
            if (type == 1 || show == "alwaysshow") {
                msgobj.find(".Validform_info").text(msg);
            }

            if (type == 1 && show != "hide" || show == "alwaysshow") {
                msghidden = false;
                msgobj.find(".iframe").css("height", msgobj.outerHeight());
                msgobj.show();
                setCenter(msgobj, 100);
            }

            if (type == 2 && o.obj) {
                o.obj.parent().next().find(".Validform_checktip").text(msg);
                Validform.util.cssctl(o.obj.parent().next().find(".Validform_checktip"), o.type);
            }

        },

        cssctl: function (obj, status) {
            switch (status) {
                case 1:
                    obj.removeClass("Validform_right Validform_wrong").addClass("Validform_checktip Validform_loading"); //checking;
                    break;
                case 2:
                    obj.removeClass("Validform_wrong Validform_loading").addClass("Validform_checktip Validform_right"); //passed;
                    break;
                case 4:
                    obj.removeClass("Validform_right Validform_wrong Validform_loading").addClass("Validform_checktip"); //for ignore;
                    break;
                default:
                    obj.removeClass("Validform_right Validform_loading").addClass("Validform_checktip Validform_wrong"); //wrong;
            }
        },

        submitForm: function (settings, flg, ajaxPost, sync) {
            /*
            flg===true时跳过验证直接提交;
            ajaxPost==="ajaxPost"指示当前表单以ajax方式提交;
            */
            var curform = this;

            //表单正在提交时点击提交按钮不做反应;
            if (curform[0].status === "posting") { return false; }

            //要求只能提交一次时;
            if (settings.postonce && curform[0].status === "posted") { return false; }

            var sync = sync === true ? false : true;
            var beforeCheck = settings.beforeCheck && settings.beforeCheck(curform);
            if (beforeCheck === false) { return false; }

            var flag = true,
				inflag;

            curform.find("[datatype]").each(function () {
                //跳过验证;
                if (flg) {
                    return false;
                }

                //隐藏的表单不做验证;
                if (settings.ignoreHidden && $(this).is(":hidden")) {
                    return true;
                }

                var inputval = Validform.util.getValue.call(curform, $(this)),
					_this;
                errorobj = _this = $(this);

                inflag = Validform.util.regcheck.call(curform, $(this).attr("datatype"), inputval, $(this));

                if (!inflag.passed) {
                    _this.addClass("Validform_error");
                    Validform.util.showmsg.call(curform, inflag.info, settings.tiptype, { obj: $(this), type: inflag.type, sweep: settings.tipSweep });

                    if (!settings.showAllError) {
                        _this.focus();
                        flag = false;
                        return false;
                    }

                    flag && (flag = false);
                    return true;
                }

                if ($(this).attr("ajaxurl")) {
                    if ($(this).attr("ignore") && $(this).attr("ignore") == "ignore" && inputval == "")
                        this.valid = "true";
                    if ($(this).attr("servercheck") && $(this).attr("servercheck") == "false")
                        this.valid = "true";
                    if (this.valid !== "true") {
                        var thisobj = $(this);
                        _this.addClass("Validform_error");
                        Validform.util.showmsg.call(curform, curform.data("tipmsg").v || tipmsg.v, settings.tiptype, { obj: thisobj, type: 3, sweep: settings.tipSweep });
                        if (!msghidden || settings.tiptype != 1) {
                            setTimeout(function () {
                                thisobj.trigger("blur", ["postform"]); //continue the form post;
                            }, 1500);
                        }

                        if (!settings.showAllError) {
                            flag = false;
                            return false;
                        }

                        flag && (flag = false);
                        return true;
                    }
                }
                _this.removeClass("Validform_error");
                errorobj = null;
                Validform.util.showmsg.call(curform, inflag.info, settings.tiptype, { obj: $(this), type: inflag.type, sweep: settings.tipSweep }, "hide");
            });

            if (settings.showAllError) {
                curform.find(".Validform_error:first").focus();
            }

            if (flag) {

                var beforeSubmit = settings.beforeSubmit && settings.beforeSubmit(curform);
                if (beforeSubmit === false) { return false; }

                curform[0].status = "posting";

                if (settings.ajaxPost || ajaxPost === "ajaxPost") {
                    Validform.util.showmsg.call(curform, curform.data("tipmsg").p || tipmsg.p, settings.tiptype, { obj: curform, type: 1, sweep: settings.tipSweep }, "alwaysshow"); //传入"alwaysshow"则让提示框不管当前tiptye为1还是2都弹出;
                    curform[0].ajax = $.ajax({
                        type: "POST",
                        dataType: "json",
                        async: sync,
                        url: curform.attr("action"),
                        //data: decodeURIComponent(curform.serialize(),true),
                        data: curform.serializeArray(),
                        success: function (data) {
                            if (data.status === "y") {
                                Validform.util.showmsg.call(curform, data.info, settings.tiptype, { obj: curform, type: 2, sweep: settings.tipSweep }, "alwaysshow");
                            } else {
                                curform[0].posting = false;
                                Validform.util.showmsg.call(curform, data.info, settings.tiptype, { obj: curform, type: 3, sweep: settings.tipSweep }, "alwaysshow");
                            }

                            settings.callback && settings.callback(data);

                            curform[0].status = "posted";
                            curform[0].ajax = null;
                        },
                        error: function (data) {
                            var msg = data.statusText === "abort" ?
									curform.data("tipmsg").abort || tipmsg.abort :
									curform.data("tipmsg").err || tipmsg.err;

                            curform[0].posting = false;
                            Validform.util.showmsg.call(curform, msg, settings.tiptype, { obj: curform, type: 3, sweep: settings.tipSweep }, "alwaysshow");
                            curform[0].status = "normal";
                            curform[0].ajax = null;
                        }
                    });

                } else {
                    if (!settings.postonce) {
                        curform[0].status = "normal";
                    }
                    return settings.callback && settings.callback(curform);
                }
            }

            return false;

        },

        resetForm: function () {
            var brothers = this;
            brothers.each(function () {
                this.reset();
                this.status = "normal";
            });

            brothers.find(".Validform_right").text("");
            brothers.find(".passwordStrength").children().removeClass("bgStrength");
            brothers.find(".Validform_checktip").removeClass("Validform_wrong Validform_right Validform_loading");
            brothers.find(".Validform_error").removeClass("Validform_error");
            brothers.eq(0).find("input:first").focus();
        },

        abort: function () {
            if (this.ajax) {
                this.ajax.abort();
            }
        }

    }

    $.Datatype = Validform.util.dataType;

    Validform.prototype = {
        dataType: Validform.util.dataType,

        eq: function (n) {
            var obj = this;

            if (n >= obj.forms.length) {
                return null;
            }

            if (!(n in obj.objects)) {
                obj.objects[n] = new Validform($(obj.forms[n]).get(), obj.settings, true);
            }

            return obj.objects[n];

        },

        resetStatus: function () {
            var obj = this;
            $(obj.forms).each(function () {
                this.status = "normal";
            });
        },

        ajaxPost: function (flag, sync) {
            var obj = this;

            //创建pop box;
            if (obj.settings.tiptype == 1 || obj.settings.tiptype == 2) {
                creatMsgbox();
            }

            Validform.util.submitForm.call($(obj.forms[0]), obj.settings, flag, "ajaxPost", sync);
        },

        submitForm: function (flag) {
            /*flag===true时不做验证直接提交*/

            var obj = this;

            //让该对象的第一个表单提交;
            var subflag = Validform.util.submitForm.call($(obj.forms[0]), obj.settings, flag);
            subflag === undef && (subflag = true);
            if (subflag === true) {
                obj.forms[0].submit();
            }
        },

        resetForm: function () {
            var obj = this;
            Validform.util.resetForm.call($(obj.forms));
        },

        abort: function () {
            var obj = this;
            $(obj.forms).each(function () {
                Validform.util.abort.call(this);
            });
        }
    }

    $.fn.Validform = function (settings) {
        return new Validform(this, settings);
    };

    function setCenter(obj, time) {
        var left = ($(window).width() - obj.outerWidth()) / 2,
			top = ($(window).height() - obj.outerHeight()) / 2,

		top = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + (top > 0 ? top : 0);

        obj.css({
            left: left
        }).animate({
            top: top
        }, { duration: time, queue: false });
    }

    function creatMsgbox() {
        if ($("#Validform_msg").length !== 0) { return false; }
        msgobj = $('<div id="Validform_msg"><div class="Validform_title">' + tipmsg.tit + '<a class="Validform_close" href="javascript:void(0);">&chi;</a></div><div class="Validform_info"></div><div class="iframe"><iframe frameborder="0" scrolling="no" height="100%" width="100%"></iframe></div></div>').appendTo("body"); //提示信息框;
        msgobj.find("a.Validform_close").click(function () {
            msgobj.hide();
            msghidden = true;
            if (errorobj) {
                errorobj.focus().addClass("Validform_error");
            }
            return false;
        }).focus(function () { this.blur(); });

        $(window).bind("scroll resize", function () {
            !msghidden && setCenter(msgobj, 400);
        });
    };

    //公用方法显示&关闭信息提示框;
    $.Showmsg = function (msg) {
        creatMsgbox();
        Validform.util.showmsg.call(win, msg, 1, {});
    };

    $.Hidemsg = function () {
        msgobj.hide();
        msghidden = true;
    };

})(jQuery, window);